88장. VPC Endpoint — VPC 안에서 외부 서비스 접근
이 장에서 말하고자 하는 것
VPC 안에서 운영하다 보면 다음과 같은 호출이 자주 일어난다.
ECS Task → S3 GetObject
ECS Task → DynamoDB Query
ECS Task → Secrets Manager
ECS Task → ECR pull image
이 호출들은 AWS 서비스 자체 를 향한다.
그런데 기본적으로 이 호출은 인터넷을 거쳐서 나간다.
ECS (프라이빗 서브넷) → NAT Gateway → 인터넷 → S3
이 구조의 문제:
- NAT Gateway 데이터 처리 비용이 든다
- 트래픽이 굳이 인터넷을 거친다 (성능 · 보안)
- NAT Gateway 가용성에 묶인다
이걸 풀어주는 게
VPC Endpoint
다.
1. VPC Endpoint가 하는 일
VPC 안에서 AWS 서비스로 가는 사설 길 을 연다
ECS (프라이빗 서브넷) → [VPC Endpoint] → S3
(인터넷 안 거침)
- NAT Gateway 비용 없음
- 트래픽이 AWS 백본 안에서만 흐름
- IAM과 결합한 추가 보안 통제 가능
2. 두 종류의 Endpoint
Gateway Endpoint
- 라우팅 테이블에 항목을 추가하는 방식
- S3, DynamoDB 만 지원
- 무료
Interface Endpoint (PrivateLink)
- 서브넷에 ENI를 만드는 방식
- 거의 모든 AWS 서비스 지원 (Secrets Manager, ECR, KMS, SQS, SNS, …)
- 시간당 + 데이터 처리 비용 있음
S3 · DynamoDB → Gateway (무료)
그 외 → Interface
3. Gateway Endpoint 동작
라우팅 테이블에 추가:
prefix list "com.amazonaws.region.s3" → vpce-xxxx
ECS Task가 S3 호출
↓ 라우팅 테이블 매칭
↓ 인터넷이 아닌 VPC Endpoint로
↓ S3
- 별도 IP 변경 필요 없음 (도메인 그대로)
- 같은 리전의 S3만 가능
4. Interface Endpoint 동작
서브넷에 ENI 생성 (사설 IP)
↓
"secretsmanager.ap-northeast-2.amazonaws.com" 도메인이
이 ENI를 가리키도록 사설 DNS 자동 설정
ECS Task → 도메인 호출 → 사설 IP → ENI → 서비스
- 사설 DNS가 자동으로 작동 (
enable_dns_hostnames = true등) - AZ 별로 ENI를 둬야 가용성 보장
5. 보안 — Endpoint Policy
Endpoint에도 정책을 붙일 수 있다.
"이 VPC Endpoint를 통해서는 우리 버킷만 접근 가능"
S3의 경우 강력한 보안 패턴:
Bucket Policy:
"특정 VPC Endpoint를 통해서만 접근 허용"
이러면 외부 인터넷이나 다른 VPC 에서는 그 버킷에 접근 불가.
6. PrivateLink — 다른 VPC / 다른 계정의 서비스에도
같은 Interface Endpoint 메커니즘으로 내 서비스를 다른 VPC에 노출 할 수도 있다.
[Provider VPC]
NLB → PrivateLink Service
↑
[Consumer VPC]
Interface Endpoint → 내부망 통신
- SaaS · 사내 서비스 공유에 자주 쓰는 패턴
- 인터넷 노출 없이 안전한 다중 VPC 연결
7. 우리 서비스에서
Gateway Endpoint:
├─ S3 (NAT 비용 절감 큼)
└─ DynamoDB (NAT 비용 절감)
Interface Endpoint:
├─ ECR + ECR DKR (Task 시작 빠름, NAT 절감)
├─ Secrets Manager
├─ Logs (CloudWatch Logs)
├─ SSM
├─ KMS
└─ STS
ECS Fargate 운영에서는 ECR · Logs · SSM Interface Endpoint 가 NAT 비용을 가장 크게 줄인다
8. NAT vs VPC Endpoint — 비용 비교
NAT Gateway: 시간당 + 처리 GB당 ($0.045/GB 수준)
S3 Gateway Endpoint: 무료
Interface Endpoint: 시간당 + 처리 GB당 (NAT의 약 60~70%)
S3 트래픽이 많다면 Gateway Endpoint 만 켜도 월 수십만 원 이상 절감되는 일이 흔하다.
9. 직접 확인해보기 — CLI
Gateway Endpoint (S3)
aws ec2 create-vpc-endpoint \
--vpc-id <vpc-id> \
--service-name com.amazonaws.ap-northeast-2.s3 \
--vpc-endpoint-type Gateway \
--route-table-ids <rtb-id-1> <rtb-id-2>
Interface Endpoint (Secrets Manager)
aws ec2 create-vpc-endpoint \
--vpc-id <vpc-id> \
--service-name com.amazonaws.ap-northeast-2.secretsmanager \
--vpc-endpoint-type Interface \
--subnet-ids <subnet-a> <subnet-b> \
--security-group-ids <sg-endpoint>
동작 확인
# Task 안에서
dig secretsmanager.ap-northeast-2.amazonaws.com
# → 사설 IP (10.0.x.x) 가 응답되어야 함
10. 코드로는 이렇게 생겼다 — Terraform
# Gateway Endpoint
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-northeast-2.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
}
resource "aws_vpc_endpoint" "dynamodb" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-northeast-2.dynamodb"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
}
# Interface Endpoint (보안 그룹은 443 인바운드 허용)
resource "aws_security_group" "endpoints" {
name = "vpc-endpoints"
vpc_id = aws_vpc.main.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [aws_security_group.task.id]
}
}
locals {
interface_endpoints = [
"ecr.api", "ecr.dkr", "secretsmanager",
"logs", "ssm", "kms", "sts"
]
}
resource "aws_vpc_endpoint" "interface" {
for_each = toset(local.interface_endpoints)
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-northeast-2.${each.value}"
vpc_endpoint_type = "Interface"
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
security_group_ids = [aws_security_group.endpoints.id]
private_dns_enabled = true
}
private_dns_enabled = true 가 핵심 — 도메인이 자동으로 사설 IP를 가리킨다.
11. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. NAT Gateway만 두고 모든 트래픽을 인터넷으로
S3 · ECR 트래픽이 누적되면 NAT 비용이 폭증한다.
가장 먼저 S3 Gateway Endpoint를 켠다
안티패턴 2. Interface Endpoint를 한 AZ에만 둔다
그 AZ가 죽으면 그 서비스 호출이 전부 실패.
사용하는 AZ 모두에 ENI
안티패턴 3. Endpoint 보안 그룹을 잘못 잡는다
Task SG에서 오는 443이 막혀 있으면 호출이 안 된다.
안티패턴 4. Bucket Policy로 Endpoint 제한을 걸고 다른 길도 열어둔다
한 길은 막고 다른 길로는 풀려 있으면 무의미.
S3 버킷 정책에서 “오직 이 VPC Endpoint” 만 허용
12. 한 줄로 정리
VPC Endpoint는 VPC 안에서 AWS 서비스로 가는 사설 길이며,
NAT 비용 절감과 보안 강화를 동시에 푼다
13. 이 장의 핵심 정리
- VPC Endpoint는 Gateway (S3 · DynamoDB) 와 Interface (그 외) 두 종류다.
- Gateway는 무료, Interface는 시간/GB 비용이 있지만 NAT보다 싸다.
- ECS Fargate는 ECR · Logs · SSM · Secrets Manager Interface Endpoint가 큰 차이를 만든다.
- Bucket Policy + Endpoint Policy로 S3 접근을 VPC 안으로 한정할 수 있다.
- Interface Endpoint는 사용하는 모든 AZ에 ENI를 둔다.
- NAT만 두지 않는다 — 가장 먼저 S3 Gateway Endpoint를 켠다.